package com.yc.cloud.openai.portal.dao.impl;

import java.io.File;
import java.util.Base64;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import com.yc.cloud.common.basic.exception.Asserts;
import com.yc.cloud.common.basic.utils.PathUtils;
import com.yc.cloud.openai.portal.dao.TextToSpeechClient;
import com.yc.cloud.openai.portal.dto.request.TextToSpeechRequest;
import com.yc.cloud.openai.portal.dto.response.TextToSpeechChatTTSResponse;
import com.yc.cloud.openai.portal.dto.response.TextToSpeechResponse;
import com.yc.cloud.openai.portal.enums.SpeechSpeaker;
import com.yc.cloud.openai.portal.utils.WebClientUtil;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import lombok.val;
import lombok.extern.slf4j.Slf4j;

@Component("CHAT_TTS")
@Slf4j
public class ChatTTSClientImpl implements TextToSpeechClient {

    private final WebClientUtil webClientUtil;
    @Value("${custom.ai.chatts.url}")
    private String URL;
    private final Integer SUCCESS_CODE = 0;
    private final PathUtils pathUtils;

    public ChatTTSClientImpl(WebClientUtil webClientUtil, PathUtils pathUtils) {
        this.webClientUtil = webClientUtil;
        this.pathUtils = pathUtils;
    }

    @Override
    public TextToSpeechResponse convertTextToSpeech(TextToSpeechRequest request) {
        // 创建一个 MultiValueMap 对象，用于存放表单数据
        MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
        formData.add("text", request.getText());
        formData.add("prompt", "");
        // 目前声音是固定死的,后面可考虑都过平台配置来获取
        formData.add("voice", request.getSpeaker().getKey().equals(SpeechSpeaker.WOMAN.getKey()) ? "3333" : "9999");
        formData.add("temperature", "0.3");
        formData.add("top_p", "0.7");
        formData.add("top_k", "20");
        formData.add("skip_refine", "0");
        // 自定义声音暂时不支持
        formData.add("custom_voice", "0");

        // 使用 WebClientUtil 发送 POST 请求
        val result = webClientUtil.postFormData(URL, formData, String.class);
        log.info("chatTTSClient result: {}", result);
        // 解析返回结果
        val chatTTSResult = JSONUtil.toBean(result, TextToSpeechChatTTSResponse.class);
        if (!Objects.equals(chatTTSResult.getCode(), SUCCESS_CODE)) {
            Asserts.fail("chatTTSClient error: " + chatTTSResult.getMsg());
            return null;
        }

        if (CollUtil.isEmpty(chatTTSResult.getAudioFiles())) {
            Asserts.fail("chatTTSClient error,no audio file found.");
            return null;
        }
        return convertResult(chatTTSResult);
    }

    /**
     * 将 chatTTS 的返回结果转换为 TextToSpeechResponse 对象
     *
     * @param chatTTSResult chatTTS 的返回结果
     * @return TextToSpeechResponse 对象
     */
    private TextToSpeechResponse convertResult(TextToSpeechChatTTSResponse chatTTSResult) {
        val textToSpeechResponse = new TextToSpeechResponse();
        val audioUrl = chatTTSResult.getAudioFiles().get(0).getUrl();
        // 为了统一url路径,我把音频数据保存到当前服务的目录下
        // TODO 是否需要base64音频数据后面在进一步评估
        val audioData = webClientUtil.getForBytes(audioUrl);
        val fileName = System.currentTimeMillis() + "." + FileUtil.getSuffix(audioUrl);
        val dstAudioFile = pathUtils.getTempBasePath() + File.separator + fileName;
        FileUtil.writeBytes(audioData, dstAudioFile);
        val audioBase64Data = Base64.getEncoder().encodeToString(audioData);
        // textToSpeechResponse.setAudioUrl(pathUtils.convertNetUrl(dstAudioFile));
        textToSpeechResponse.setAudioData(audioBase64Data);
        return textToSpeechResponse;
    }
}
